/*
 * File Name：PushTopController.java
 * Copyright：Copyright 2008-2014 CiWong.Inc. All Rights Reserved.
 * Description： PushTopController.java
 * Modify By：res-jianpingliu
 * Modify Date：2014-9-12
 * Modify Type：Add
 */
package com.ciwong.mobilelib.widget.listview;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.TextView;

/**
 * 上推置顶的算法
 * 
 * @author res-jianpingliu
 * @version ciwong v.1.0 2014-9-12
 * @since ciwong v.1.0
 */
public class PushTopController
{
    /**
     * 隐藏状态
     */
    public static final int PINNED_TOP_GONE = 0;

    /**
     * 显示状态
     */
    public static final int PINNED_TOP_VISIBLE = 1;

    /**
     * 表示mHeaderView在上升状态
     */
    public static final int PINNED_TOP_PUSHED_UP = 2;

    /**
     * 表示mHeaderView在下拉状态
     */
    public static final int PINNED_TOP_PUSHED_DOWN = 3;

    private final int defaultAlpha = 255;

    private final int two = 2;

    private View mTopView;

    private int mTopViewId;// 头标签的id -- R.id.XXXX

    private boolean mTopViewVisible = false;// 是否显示头标题

    private int mTopViewY = 0;// 头标签应该显示的Y轴坐标

    private String mTopViewText = "A";

    private int mTopViewstate = PINNED_TOP_GONE;

    private int mTopViewWidth;

    private int mTopViewHeight;

    private Context context;

    private AbsListView absListView;

    public PushTopController(Context c, AbsListView v)
    {
        context = c;
        absListView = v;
    }

    /**
     * 设置头标签控件
     * 
     * @param context
     *            上下文
     * @param layout
     *            头标签的layoutID
     * @param textViewId
     *            头标签的ID
     */
    public void setPinnedTopView(int layout, int textViewId)
    {
        // 根据控件layout和上下文对象生成头标签VIew
        mTopView = LayoutInflater.from(context).inflate(layout, absListView,
                false);
        mTopViewId = textViewId;// 保存文本控件的id
        if (mTopView != null)
        {
            absListView.setFadingEdgeLength(0);// 设置边缘 没有设置的拖动listview上下边缘会出现颜色
        }
        absListView.requestLayout();// 调整布局
    }

    /**
     * 配置头标签（显示位置，颜色，透明度字体等
     * 
     * @param position
     */
    public void configureHeaderView()
    {
        if (mTopView == null)
        {
            return;
        }

        switch (mTopViewstate)
        {
            case PINNED_TOP_GONE:
            {
                // 头标签不显示
                mTopViewVisible = false;
                break;
            }
            case PINNED_TOP_VISIBLE:
            {
                // 头表签显示（默认状态）
                configurePinnedHeader(mTopView, defaultAlpha);// 设置头标签的文字和透明度
                if (mTopView.getTop() != 0)
                {
                    mTopView.layout(0, 0, mTopViewWidth, mTopViewHeight);// 设置头标签的显示位置（最初的默认原始状态
                }
                mTopViewVisible = true;
                break;
            }
            case PINNED_TOP_PUSHED_UP:
            {
                // 头标签上升状态
                mTopView.layout(0, mTopViewY, mTopViewWidth, mTopViewHeight
                        + mTopViewY);
                mTopViewVisible = true;
                break;
            }
            case PINNED_TOP_PUSHED_DOWN:// 头标签的下拉状态
                mTopView.layout(0, mTopViewY, mTopViewWidth, mTopViewHeight
                        + mTopViewY);
                mTopViewVisible = true;
                break;
        }
    }

    /**
     * 设置头标签的显示文本和状态
     * 
     * @param headerViewText
     *            文本内容
     * @param headerViewstate
     *            标签状态
     */
    public  void setHeaderViewTextAndState(String headerViewText, int headerViewstate)
    {
        this.mTopViewText = headerViewText;
        this.mTopViewstate = headerViewstate;
        refreshView(absListView.getChildCount());// 刷新头标签
    }

    /**
     * 设置是否显示头标签是否显示
     * 
     * @param meaderViewVisible
     *            是否显示
     */
    public void setmHeaderViewVisible(boolean meaderViewVisible)
    {
        this.mTopViewVisible = meaderViewVisible;
    }

    /**
     * 配置头标签
     * 
     * @param header
     *            头标签
     * @param alpha
     *            透明度
     */
    public void configurePinnedHeader(View header, int alpha)
    {
        TextView lSectionHeader = (TextView) header;
        lSectionHeader.setText(mTopViewText);
        Drawable textBgDrawable = lSectionHeader.getBackground();
        // textBgDrawable.setAlpha(alpha);
        lSectionHeader.setBackgroundDrawable(textBgDrawable);
        // lSectionHeader.setTextColor(alpha << offset24
        // | (lSectionHeader.getCurrentTextColor() & offsetColor));
    }

    /**
     * 刷新头标签
     * 
     * @param visibleItemCount
     *            listview显示的列表
     */
    public void refreshView(int visibleItemCount)
    {
        if (visibleItemCount == 0)
        {
            View v = absListView.getChildAt(visibleItemCount);
            if (v != null && v.getTop() < 0)
            {
                mTopViewstate = PINNED_TOP_VISIBLE;
            }
        }
        View firstView = absListView.getChildAt(0);// 获得显示的第一个控件
        View secondView = null;
        if (visibleItemCount > two)
        {
            secondView = absListView.getChildAt(1);// 获得显示的第二个控件
        }
        if (secondView == null)// 无第二项，也就没有拖动的必要，不用进行对头标签的绘制变化
        {
            configureHeaderView();// 刷新头标签，然后return
            return;
        }
        if (firstView != null)
        {
            // 获得第一和第二个项的标签
            View firstTvCatalog = firstView.findViewById(mTopViewId);
            View secondTvCatalog = secondView.findViewById(mTopViewId);
            if (firstTvCatalog == null || secondTvCatalog == null)
            {
                configureHeaderView();// 刷新头标签，然后return
                return;
            }

            if (secondTvCatalog.getVisibility() == View.GONE
                    && firstTvCatalog.getVisibility() == View.GONE)
            {
                mTopViewstate = PINNED_TOP_VISIBLE;// 恢复默认的状态
            }

            // 第一项存在
            mTopViewText = (String) firstTvCatalog.getTag();// 获得第一项的标签保存的文本
            int firstBottom = firstView.getBottom();// 获得第一项的底部距离顶部的高度
            int headerHeight = mTopView.getHeight();// 获得头标签的高度
            // 当第一个的底部距离顶部的高度 头标签的高度小时，说明头标签的位置需要表化来使下 含标签的项与头标签粘在一起
            if (firstBottom < headerHeight)
            {
                mTopViewY = firstBottom - headerHeight;// 头标签显示的Y轴位置
                // 透明度根据头标签升的高度来定
                // mHeaderViewAlpha = defaultAlpha * (headerHeight +
                // mHeaderViewY)
                // / headerHeight;
            }
            else
            {
                mTopViewY = 0;
                // mHeaderViewAlpha = defaultAlpha;
            }

            if (secondTvCatalog.getVisibility() == View.VISIBLE)// 第二项的标签存在
            {
                // 头标签的top大小和mHeaderViewY不等。说明需要移动头标签
                if (headerHeight < firstBottom)// 头标签下面
                {
                    mTopViewstate = PINNED_TOP_PUSHED_DOWN;
                }
                else if (headerHeight > firstBottom)// 说明是头标签上移
                {
                    mTopViewstate = PINNED_TOP_PUSHED_UP;
                }
                else if (headerHeight == firstBottom)// mHeaderView底部与下面的标签顶部重合
                {
                    mTopViewstate = PINNED_TOP_VISIBLE;
                }
            }

            if (firstTvCatalog.getVisibility() == View.VISIBLE)
            {
                if (firstView.getTop() == 0)// mHeaderView与listview的标签重写
                {
                    mTopViewstate = PINNED_TOP_VISIBLE;
                }
                // firstTvCatalog显示，secondTvCatalog不显示，说明不用维持头标签的变化，设置默认状态
                if (secondTvCatalog.getVisibility() == View.GONE)
                {
                    mTopViewstate = PINNED_TOP_VISIBLE;
                }
            }
            configurePinnedHeader(mTopView, 0);
            configureHeaderView();
        }
    }

    public boolean isTopViewVisible()
    {
        return mTopViewVisible;
    }

    public void setTopViewVisiable(boolean visiable)
    {
        mTopViewVisible = visiable;
    }

    public View getTopView()
    {
        return mTopView;
    }

    public int getTopViewWidth()
    {
        return mTopViewWidth;
    }

    public void setTopViewWidth(int width)
    {
        this.mTopViewWidth = width;
    }

    public int getTopViewHeight()
    {
        return mTopViewHeight;
    }

    public void setTopViewHeight(int height)
    {
        this.mTopViewHeight = height;
    }

    public void setTopState(int state)
    {
        mTopViewstate = state;
    }

}
